/*
 * Created on Jul 17, 2005
 *
 */
package org.mushroomdb.server;

import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

import org.apache.log4j.Logger;
import org.mushroomdb.exception.RDBMSRuntimeException;


/**
 * @author Matu
 *
 */
public class ShutdownHook implements Runnable {
	
	private final static String SHUTDOWN_MESSAGE = "<shutdown/>"; //$NON-NLS-1$
	private ConnectionDispatcher connectionDispatcher;
	private int port;
	private Logger logger;

	/**
	 * Constructor.
	 */
	public ShutdownHook(ConnectionDispatcher connectionDispatcher, int port) {
		this.connectionDispatcher = connectionDispatcher;
		this.port = port;
		this.logger = Logger.getLogger(this.getClass());
	}

	/**
	 * @see java.lang.Runnable#run()
	 */
	public void run() {
		
		this.logger.warn("ShutdownHook started on port " + this.port); //$NON-NLS-1$
		
		boolean shutdownSignal = false;
		char[] chars = new char[SHUTDOWN_MESSAGE.length()];
		
		ServerSocket serverSocket = null;
		
		try {
			serverSocket = new ServerSocket(this.port);
			while (!shutdownSignal) {
				try {
					
					Socket socket = serverSocket.accept();
					InputStreamReader reader = new InputStreamReader(socket.getInputStream());
					
					int readCount = 0;
					StringBuffer buffer = new StringBuffer();
					while (readCount != -1 && buffer.length() < 20 && !shutdownSignal) {
						readCount = reader.read(chars);
						String fragment = new String(chars,0,readCount);
						buffer.append(fragment);
						if (SHUTDOWN_MESSAGE.equals(buffer.toString())) {
							this.logger.warn("Shutdown signal recieved: system shutdown initiated."); //$NON-NLS-1$
							shutdownSignal = true;
							
							Thread thread = new Thread(new Runnable() {
								public void run() {
									Thread.currentThread().setName("Shutdown Thread"); //$NON-NLS-1$
									ShutdownHook.this.connectionDispatcher.initiateShutdown();
								}
							});
							thread.start();
						}
					}
					reader.close();
					
				} catch (IOException e) {
					throw new RDBMSRuntimeException(e);
				}
			}
		} catch (IOException e) {
			throw new RDBMSRuntimeException(e);
		}
	}

}
